package com.cms.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cms.entity.Menu;
import com.cms.mapper.MenuMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.builder.CompareToBuilder;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 菜单表 服务实现类
 * </p>
 *
 * @author songfayuan
 * @since 2021-11-12
 */
@Service
public class MenuService extends ServiceImpl<MenuMapper, Menu> {

    /**
     * 查找顶级菜单
     *
     * @return 顶级菜单
     */
    public List<Menu> findRoots(){
        QueryWrapper<Menu> queryWrapper = new QueryWrapper();
        queryWrapper.isNull("parentId");
        queryWrapper.eq("isShow",true);
        queryWrapper.orderByDesc("sort");
        return baseMapper.selectList(queryWrapper);
    }


    /**
     * 查找下级菜单
     *
     * @param menuId
     *            菜单Id
     * @param isShow
     *            是否显示
     * @param recursive
     *            是否递归
     *
     * @return 下级菜单
     */
    public List<Menu> findChildren(Integer menuId, Boolean isShow, Boolean recursive){
        QueryWrapper<Menu> queryWrapper = new QueryWrapper();
        if(isShow!=null){
            queryWrapper.eq("isShow",isShow);
        }
        if(recursive){
            queryWrapper.orderByAsc("grade").orderByDesc("sort");
            List<Menu> menus;
            if(menuId!=null){
                queryWrapper.like("treePath",","+menuId+",");
                menus = baseMapper.selectList(queryWrapper);
            }else{
                menus = baseMapper.selectList(queryWrapper);
            }
            sort(menus);
            return menus;
        }else{
            queryWrapper.eq("parentId",menuId);
            queryWrapper.orderByDesc("sort");
            return baseMapper.selectList(queryWrapper);
        }
    }

    /**
     * 查找菜单树
     *
     * @return 菜单树
     */
    public List<Menu> findTree(){
        return findChildren(null,null,true);
    }


    /**
     * 排序菜单
     *
     * @param menus
     *           菜单
     */
    private void sort(List<Menu> menus) {
        if(menus == null || menus.size()==0) {
            return;
        }
        final Map<Integer, Integer> sortMap = new HashMap<Integer, Integer>();
        for (Menu menu : menus) {
            sortMap.put(menu.getId(), menu.getSort());
        }
        Collections.sort(menus, new Comparator<Menu>() {
            @Override
            public int compare(Menu menu1, Menu menu2) {
                Integer[] ids1 = (Integer[]) ArrayUtils.add(menu1.getParentIds(), menu1.getId());
                Integer[] ids2 = (Integer[]) ArrayUtils.add(menu2.getParentIds(), menu2.getId());
                Iterator<Integer> iterator1 = Arrays.asList(ids1).iterator();
                Iterator<Integer> iterator2 = Arrays.asList(ids2).iterator();
                CompareToBuilder compareToBuilder = new CompareToBuilder();
                while (iterator1.hasNext() && iterator2.hasNext()) {
                    Integer id1 = iterator1.next();
                    Integer id2 = iterator2.next();
                    Integer sort1 = sortMap.get(id1);
                    Integer sort2 = sortMap.get(id2);
                    compareToBuilder.append(sort2,sort1).append(id1, id2);
                    if (!iterator1.hasNext() || !iterator2.hasNext()) {
                        compareToBuilder.append(menu1.getGrade(), menu2.getGrade());
                    }
                }
                return compareToBuilder.toComparison();
            }
        });
    }
}
